#include<bits/stdc++.h>
using namespace std;
#define y1 abbbbb
using ll = long long;
const int N = 2e5 + 7;
int lowbit(int x) { return x & (-x);} 

// 二维数点   扫描线 + 树状数组 + 离散化 
// 对 x 离散化   
// 平行于 x轴 的扫描线，则需把同一水平线上所有的操作事件完成，才能上移扫描线 
// 在线 -> 离线 
 
vector<int> vx;
vector<array<int, 4>> event;
int n, q, m;
int bit[N * 4], ans[N];
 
int query(int x) { // 1...x 的前缀和（"1"的个数） 
	int s = 0;
	for(; x; x -= lowbit(x))
		s += bit[x];
	return s;
}
void change(int x, int s) { // a[x] += s
	for(; x <= m; x += lowbit(x))
		bit[x] += s; 
}
int main() {
	scanf("%d%d", &n, &q);
	for(int i = 1; i <= n; i++) {
		int x, y;
		scanf("%d%d", &x, &y);
		vx.push_back(x);
		// y坐标     类型 插点:0    x坐标
		//顺序只要满足 y第一位、先插入再操作、操作次序最后 即可
		// y  x   op  rk
		// y  op  x   rk 
		event.push_back({y, 0, x}); 
	}	
	for(int i = 1; i <= q; i++) {
		int x1, x2, y1, y2;
		scanf("%d%d%d%d", &x1, &x2, &y1, &y2);
		// 容斥求个数   减1   加2 
		event.push_back({y2, 2, x2, i}); 
		event.push_back({y1 - 1, 2, x1 - 1, i}); 
		event.push_back({y2, 1, x1 - 1, i}); 
		event.push_back({y1 - 1, 1, x2, i}); 
	}
	// vx离散化 
	sort(event.begin(), event.end());
	sort(vx.begin(), vx.end());
	vx.erase(unique(vx.begin(), vx.end()), vx.end());
	m = vx.size(); 
	
	for(auto evt : event) {
		if(evt[1] == 0) { // 插入点 (先把同一y坐标下的插点事件完成) 
			int y = lower_bound(vx.begin(), vx.end(), evt[2]) - vx.begin() + 1; // 树状数组不能用0-base,要用1-base 
			change(y, 1);
		} else { // 查询 点总个数 
			int y = upper_bound(vx.begin(), vx.end(), evt[2]) - vx.begin() + 1 - 1;
			int tmp = query(y);
			if(evt[1] == 1)
				ans[evt[3]] -= tmp;
			else
				ans[evt[3]] += tmp;
		}
	}
	for(int i = 1; i <= q; i++) {
		printf("%d\n", ans[i]);
	}
	
	return 0;
}